<?php

namespace app\service;

use app\model\TicketOrders;
use app\model\TicketRefunds;
use app\model\TravelCoupon;
use app\model\TravelCouponUser;
use app\service\UserService;
use think\Request;
use app\model\Tickets;
use app\model\TicketVerifications;
use app\model\User;
use app\model\UserAccountRecord;
use app\model\Orders;
use app\model\OrderProducts;
use app\model\OrderCoupon;
use app\model\OrderTotals;
use app\model\CartProducts;
use app\model\OrderHistories;
use app\model\OrderPayments;
use app\model\PayRecord;
use app\model\Products;
use app\model\ProductSkus;
use app\model\ProductDescriptions;
use app\model\RmaHistories;
use app\model\RmaReasons;
use app\model\Rmas;
use app\model\Sellers;
use app\model\UserAddresses;
use think\facade\Db;

class OrderService
{
    public static function submitTicketOrders($params)
    {
        $userId = UserService::getCurrentUser();
        // {"tickets":[{"ticket_id":1,"quantity":1,"price":"188.00"}],"coupon_id":10,"original_amount":188,"final_amount":178,"payment_method":"balance"}array(5) {
        // 计算订单金额
        // 获取门票信息
        $params['coupon_id'] = isset($params['coupon_id']) ? (int)$params['coupon_id'] : 0;
        $ticketIds = array_column($params['tickets'], 'ticket_id');
        $tickets = Tickets::whereIn('id', $ticketIds)->select()->toArray();
        $tickList = array_column($params['tickets'], null, 'ticket_id');
        // 检查门票是否过期
        $currentTime = time();
        $orders = [];
        $nowTime = date('Y-m-d H:i:s');
        foreach ($tickets as $key => $ticket) {
            if (strtotime($ticket['valid_end'] . ' 23:59:59') < $currentTime) {
                throw new \Exception('门票' . $ticket['name'] . '已过期');
            }
            // 检查库存
            if ($ticket['stock'] < $tickList[$ticket['id']]['quantity']) {
                throw new \Exception('门票' . $ticket['name'] . '库存不足');
            }
            // 检测状态
            if ($ticket['status'] != 1) {
                throw new \Exception('门票' . $ticket['name'] . '已下架');
            }
            $totalAmount = round((float)bcmul((string)$tickList[$ticket['id']]['quantity'], (string)$ticket['price'], 6), 2);
            $orders[] = [
                'order_sn' => generateOrderNumber('T'),
                'user_id' => $userId['user_id'],
                'ticket_id' => $ticket['id'],
                'quantity' => $tickList[$ticket['id']]['quantity'],
                'unit_price' => $ticket['price'],
                'total_amount' => $totalAmount,
                'status' => 1,
                'pay_type' => $params['payment_method'] == 'balance' ? 3 : 1,
                'created_at' => $nowTime,
                'coupon_user_id' => 0, //$params['coupon_id'],
                'discount_amount' => 0,
                'pay_amount' => $totalAmount,
            ];
        }
        if (empty($orders)) {
            throw new \Exception('创建失败');
        }

        // 检查优惠券并计算优惠分摊
        $useCouponId = 0;
        $totalAmount = array_sum(array_column($orders, 'pay_amount'));
        if ($params['recive_coupon_id']) {
            $coupon = TravelCouponUser::alias('cu')
                ->leftJoin('travel_coupons c', 'cu.coupon_id=c.id')
                ->where('cu.id', $params['recive_coupon_id'])
                ->where('cu.status', 1)
                ->field('c.*')
                ->find();
            if ($coupon) {
                if ($coupon['status'] != 2) {
                    throw new \Exception('优惠券已失效');
                }
                // 检查使用门槛
                if ($totalAmount < $coupon['min_spend']) {
                    throw new \Exception('订单金额未达到优惠券使用门槛');
                }
                // 计算优惠金额
                $discountAmount = 0;
                switch ($coupon['discount_type']) {
                    case 1: // 满减
                        $discountAmount = $coupon['discount_amount'];
                        break;
                    case 2: // 直减
                        $discountAmount = $coupon['discount_amount'];
                        break;
                    case 3: // 折扣
                        $discountAmount = $totalAmount * (1 - $coupon['discount_rate'] / 10);
                        break;
                }

                // 确保优惠金额不超过订单总金额
                $discountAmount = min($discountAmount, $totalAmount);
                // 按订单金额比例分摊优惠
                $remainingDiscount = $discountAmount;
                $orderCount = count($orders);

                foreach ($orders as $index => &$order) {
                    if ($index == $orderCount - 1) {
                        // 最后一个订单承担剩余的优惠金额，避免精度问题
                        $orderDiscount = $remainingDiscount;
                    } else {
                        // 按比例分摊优惠金额
                        $orderDiscount = round($discountAmount * ($order['total_amount'] / $totalAmount), 2);
                        $remainingDiscount -= $orderDiscount;
                    }

                    $order['discount_amount'] = $orderDiscount;
                    $order['pay_amount'] = $order['total_amount'] - $orderDiscount;

                    // 确保实付金额不为负数
                    if ($order['pay_amount'] < 0) {
                        $order['pay_amount'] = 0;
                    }
                    $order['coupon_user_id'] = $params['recive_coupon_id'];
                }
                $useCouponId = $params['recive_coupon_id'];
                unset($order); // 解除引用
            } else {
                throw new \Exception('优惠券不存在');
            }
        }


        $totalAmount = array_sum(array_column($orders, 'pay_amount'));
        try {

            if ($params['payment_method'] == 'balance') {
                Db::startTrans();
                // 检查余额是否足够
                $balance = User::where('id', $userId['user_id'])->value('balance');
                if ($balance < $totalAmount) {
                    throw new \Exception('余额不足');
                }
                foreach ($orders as $key => $order) {
                    $orders[$key]['status'] = 1;
                    $orders[$key]['pay_time'] = $nowTime;
                }
                // 扣除余额
                User::where('id', $userId['user_id'])->dec('balance', $totalAmount)->update();
                $records = [];
                $verifRecord = [];
                foreach ($orders as $key => $order) {
                    $records[] = [
                        'user_id' => $userId['user_id'],
                        'record_type' => 'balance',
                        'change_type' => 2,
                        'amount' => $order['pay_amount'],
                        'before_balance' => $userId['balance'],
                        'relation_id' => 0,
                        'source_type' => 'order',
                        'source_id' => $order['order_sn'],
                        'remark' => '订单支付',
                        'status' => 1,
                        'created_at' => $nowTime,
                    ];
                    $verifRecord[] = [
                        'order_id' => 0,
                        'ticket_id' => $order['ticket_id'],
                        'user_id' => $userId['user_id'],
                        'verification_code' => generateVerifyCode(10),
                        'status' => 0
                    ];
                }
                UserAccountRecord::insertAll($records);
                // 创建门票订单
                // TODO: 在这里添加订单创建逻辑
                //1.判断支付是否余额支付
                //   余额支付，直接订单成功，写入余额使用记录表
                //创建订单
                // 创建核销门票核销信息
                //更改优惠卷记录已使用
                $orderResult = TicketOrders::saveAll($orders);
                $oid = [];
                if (!$orderResult) {
                    throw new \Exception('创建失败');
                }
                foreach ($orderResult as $key => $order) {
                    if (!empty($verifRecord)) {
                        $verifRecord[$key]['order_id'] = $order['id'];
                    }
                    $oid[] = $order['id'];
                }

                // 支付成功后才产生
                TicketVerifications::insertAll($verifRecord);
                if ($useCouponId) {
                    TravelCouponUser::where('id', $useCouponId)->update([
                        'status' => 2,
                        'used_at' => $nowTime,
                        'order_id' => implode(',', $oid),
                    ]);
                }
                Db::commit();
                return [
                    'msg' => '支付成功',
                    'is_pay' => 0,
                ];
            } else {
                //微信支付、 $verifRecord支付成功后才产生
            }
        } catch (\Exception $e) {
            Db::rollback();
            throw new \Exception($e->getMessage());
        }
    }

    public static function getTicketOrderList($userId, $page, $pageSize)
    {
        $where = [];
        $where[] = ['to.user_id', '=', $userId];
        $where[] = ['to.status', 'in', [1, 3, 4, 5]];
        // 查询订单列表，关联门票信息和核销记录
        $query = TicketOrders::alias('to')
            ->leftJoin('tickets t', 'to.ticket_id = t.id')
            ->leftJoin('scenic_spots ss', 't.scenic_id = ss.id')
            ->where($where)
            ->field([
                'to.id',
                'to.order_sn',
                'to.status',
                'to.quantity',
                'to.unit_price',
                'to.total_amount',
                'to.discount_amount',
                'to.pay_amount',
                'to.created_at',
                'to.pay_time',
                't.title as ticket_name',
                'ss.cover_image as ticket_image',
                'ss.name as scenic_spot_name'
            ])
            ->order('to.created_at', 'desc');

        // 分页查询
        $total = $query->count();
        $list = $query->page($page, $pageSize)->select()->toArray();
        // 获取每个订单的核销信息
        if (!empty($list)) {
            $orderIds = array_column($list, 'id');
            // 查询核销记录，统计已核销数量
            $verifications = TicketVerifications::whereIn('order_id', $orderIds)
                ->field('order_id, verification_code, status')
                ->select()
                ->toArray();

            // 按订单ID分组核销记录
            $verificationsByOrder = [];
            foreach ($verifications as $verification) {
                $orderId = $verification['order_id'];
                if (!isset($verificationsByOrder[$orderId])) {
                    $verificationsByOrder[$orderId] = [
                        'total' => 0,
                        'verified' => 0,
                        'codes' => []
                    ];
                }
                $verificationsByOrder[$orderId]['total']++;
                $verificationsByOrder[$orderId]['codes'][] = $verification['verification_code'];
                if ($verification['status'] == 1) { // 已核销
                    $verificationsByOrder[$orderId]['verified']++;
                }
            }

            // 为每个订单添加核销信息
            foreach ($list as &$order) {
                $orderId = $order['id'];
                $order['verified_count'] = isset($verificationsByOrder[$orderId])
                    ? $verificationsByOrder[$orderId]['verified'] : 0;
                // 获取第一个核销码作为展示用
                $order['verification_code'] = isset($verificationsByOrder[$orderId]) && !empty($verificationsByOrder[$orderId]['codes'])
                    ? $verificationsByOrder[$orderId]['codes'][0] : '';
                // 格式化金额
                // $order['unit_price'] = round((float)$order['unit_price'], 2);
                // $order['total_amount'] = round((float)$order['total_amount'], 2);
                // $order['discount_amount'] = round((float)$order['discount_amount'], 2);
                // $order['pay_amount'] = round((float)$order['pay_amount'], 2);

                // 处理图片URL
                if ($order['ticket_image'] && strpos($order['ticket_image'], 'http') !== 0) {
                    $order['ticket_image'] = env('IMAGE_URL') . $order['ticket_image'];
                }
                $order['order_status_desc'] = TicketOrders::$orderStatus[$order['status']];
                // $order['payment_method_desc'] = TicketOrders::$paymentMethod[$order['payment_method']];
            }
        }

        // 计算是否还有更多数据
        $hasMore = ($page * $pageSize) < $total;
        return [
            'list' => $list,
            'total' => $total,
            'page' => $page,
            'pageSize' => $pageSize,
            'hasMore' => $hasMore
        ];
    }


    public static function refundTicketOrder($userId, $params)
    {
        $order = TicketOrders::where('order_sn', $params['order_sn'])->where('user_id', $userId)->find();
        if (!$order) {
            throw new \Exception('订单不存在');
        }
        if ($order['status'] != 1) {
            throw new \Exception('订单状态错误,无法退款');
        }
        // 检测是否核销数量1
        if ($order['verified_count'] > 0) {
            throw new \Exception('订单已核销,无法退款');
        }


        // 检测是否余额支付，余额支付退回余额
        if ($order['pay_type'] == 3) {
            return self::refundBalance($userId, $order);
        }
    }

    // 退回余额
    public static function refundBalance($userId, $order)
    {
        $beforBalance = UserService::getCurrentUserBalance();
        // 退余额，记录钱包记录，更改订单状态
        try {
            Db::startTrans();
            // 退回余额
            UserAccountRecord::insert([
                'user_id' => $userId,
                'record_type' => 'balance',
                'change_type' => 1,
                'amount' => $order['pay_amount'],
                'before_balance' => $beforBalance,
                'source_type' => 'order',
                'source_id' => $order['id'],
                'remark' => '退款',
                'status' => 1,
                'created_at' => date('Y-m-d H:i:s'),
            ]);
            TicketRefunds::insert([
                'order_id' => $order['id'],
                'user_id' => $userId,
                'refund_sn' => generateOrderNumber('R'),
                'refund_amount' => $order['pay_amount'],
                'refund_reason' => '用户申请退款',
                'status' => 1,
                'pay_type' => 3,
                'requested_at' => date('Y-m-d H:i:s'),
                'processed_at' => date('Y-m-d H:i:s'),
            ]);
            TicketOrders::where('id', $order['id'])->update([
                'status' => 5,
                'updated_at' => date('Y-m-d H:i:s'),
            ]);
            TicketVerifications::where('order_id', $order['id'])->update([
                'status' => 3
            ]);
            // 判断是否使用优惠卷
            if ($order['coupon_user_id']) {
                $couponRes = TravelCouponUser::where('id', $order['coupon_user_id'])->find();

                if (!empty($couponRes)) {
                    $couponRes = $couponRes->toArray();
                    $couponRes['order_id'] = explode(',', $couponRes['order_id']);
                    // 判断是否都是已经作废
                    if (TicketOrders::whereIn('id', $couponRes['order_id'])->where('status', 5)->count() == count($couponRes['order_id'])) {
                        TravelCouponUser::where('id', $order['coupon_user_id'])->update([
                            'status' => 1,
                            'used_at' => null,
                            'order_id' => '',
                        ]);
                    }
                }
            }
            User::where('id', $userId)->inc('balance', $order['pay_amount'])->update();
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            trace($e, 'error');
            throw new \Exception($e->getMessage());
            return false;
        }
        return true;
    }

    // 核销门票
    public static function verifyTicket($verificationCode)
    {
        $user = UserService::getCurrentUser();
        // 根据核销码查询核销记录
        $verification = TicketVerifications::alias('tv')
            ->leftJoin('ticket_orders to', 'tv.order_id = to.id')
            ->leftJoin('tickets t', 'tv.ticket_id = t.id')
            ->leftJoin('scenic_spots ss', 't.scenic_id = ss.id')
            ->where('tv.verification_code', $verificationCode)
            ->field([
                'tv.id as verification_id',
                'tv.order_id',
                'tv.ticket_id',
                'tv.user_id',
                'tv.verification_code',
                'tv.status as verification_status',
                'tv.verified_at',
                'to.order_sn',
                'to.quantity',
                'to.unit_price',
                'to.total_amount',
                'to.status as order_status',
                'to.verified_count',
                't.title as ticket_name',
                't.valid_start',
                't.valid_end',
                'ss.name as scenic_spot_name'
            ])
            ->find();

        if (!$verification) {
            throw new \Exception('核销码不存在');
        }
        // 检查核销码状态
        if ($verification['verification_status'] == 1) {
            throw new \Exception('核销码已使用');
        }
        // 检查核销码状态
        if ($verification['verification_status'] != 0) {
            throw new \Exception('核销码错误：' . TicketVerifications::$verificationStatus[$verification['verification_status']]);
        }
        // 检查订单状态
        if ($verification['order_status'] != 1) {
            throw new \Exception('订单状态异常，无法核销');
        }

        // 检查门票有效期
        $currentDate = date('Y-m-d');
        if ($currentDate < $verification['valid_start'] || $currentDate > $verification['valid_end']) {
            throw new \Exception('门票不在有效期内');
        }
        try {
            Db::startTrans();
            // 更新核销记录状态
            TicketVerifications::where('id', $verification['verification_id'])
                ->update([
                    'status' => 1,
                    'verified_at' => date('Y-m-d H:i:s'),
                    'verified_by' => $user['username'],
                    'remark' => '已完成核销'
                ]);
            // 查询该订单的核销情况，更新订单状态
            $orderVerifications = TicketVerifications::where('order_id', $verification['order_id'])
                ->field('status')
                ->select()
                ->toArray();

            $totalCount = count($orderVerifications);
            $verifiedCount = 0;
            foreach ($orderVerifications as $v) {
                if ($v['status'] == 1) {
                    $verifiedCount++;
                }
            }

            // 更新订单状态
            $newOrderStatus = 1; // 默认保持已支付状态
            if ($verifiedCount == $totalCount) {
                $newOrderStatus = 3; // 已使用
            } elseif ($verifiedCount > 0) {
                $newOrderStatus = 4; // 部分使用
            }
            TicketOrders::where('id', $verification['order_id'])
                ->update([
                    'status' => $newOrderStatus,
                    'verified_count' => Db::raw('verified_count+' . $verification['quantity']),
                    'updated_at' => date('Y-m-d H:i:s'),
                ]);
            Db::commit();
            return [
                'verification_code' => $verification['verification_code'],
                'ticket_name' => $verification['ticket_name'],
                'scenic_spot_name' => $verification['scenic_spot_name'],
                'order_sn' => $verification['order_sn'],
                'unit_price' => $verification['unit_price'],
                'verified_count' => $verification['verified_count'], //$verifiedCount,
                'total_count' => $verification['quantity'], //$totalCount,
                'verified_at' => date('Y-m-d H:i:s'),
                'status' => 'valid'
            ];
        } catch (\Exception $e) {
            Db::rollback();
            throw new \Exception('核销失败：' . $e->getMessage());
        }
    }



    // 创建商城订单
    public static function createMallOrder($params)
    {
        // 获取当前用户信息
        $user = UserService::getCurrentUser();
        if (!$user) {
            throw new \Exception('用户未登录');
        }
        $userId = $user['user_id'];

        // 参数验证
        $addressId = isset($params['address_id']) ? (int)$params['address_id'] : 0;
        $couponId = isset($params['coupon_id']) ? (int)$params['coupon_id'] : 0;
        $paymentType = $params['payment_type'] ?? '';
        $remark = $params['remark'] ?? '';

        if (!$addressId) {
            throw new \Exception('请选择收货地址');
        }
        if (!$paymentType) {
            throw new \Exception('请选择支付方式');
        }

        // 开启事务


        try {
            // 3. 查询用户收货地址信息
            $address = UserAddresses::where('id', $addressId)
                ->where('customer_id', $userId)
                ->find();
            if (!$address) {
                throw new \Exception('收货地址不存在');
            }
            if ($couponId > 0) {
                // 查询用户优惠券
                $userCoupon = TravelCouponUser::where('id', $couponId)
                    ->where('user_id', $userId)
                    ->where('status', 1) // 未使用
                    ->find();
                if (!$userCoupon) {
                    throw new \Exception('优惠券不存在或已使用');
                }
                // 查询优惠券详情
                $coupon = TravelCoupon::where('id', $userCoupon['coupon_id'])
                    ->where('status', 2) // 进行中
                    ->find();
                if (!$coupon) {
                    throw new \Exception('优惠券已失效');
                }
                $coupon = $coupon->toArray();
                // 检查优惠券有效期
                $now = time();
                if ($now < strtotime($coupon['start_time']) || $now > strtotime($coupon['end_time'])) {
                    throw new \Exception('优惠券已过期');
                }

                // 检查使用场景（3=线上商城）
                $coupon['usage_type'] = json_decode($coupon['usage_type'], true);
                if (!in_array(3, $coupon['usage_type'])) {
                    throw new \Exception('该优惠券不适用于商城订单');
                }
                $couponInfo = $coupon;
            }
            // 1. 查询购物车选择的产品信息
            $cartItems = CartProducts::alias('cp')
                ->leftJoin('products p', 'cp.product_id = p.id')
                ->leftJoin('product_skus ps', 'cp.product_sku = ps.id')
                ->leftJoin('product_descriptions pd', 'p.id = pd.product_id')
                ->where('cp.customer_id', $userId)
                ->where('cp.selected', 1)
                ->where('p.active', 1)
                ->where('pd.locale', 'zh_cn')
                ->field([
                    'cp.id as cart_id',
                    'cp.product_id',
                    'cp.product_sku',
                    'cp.quantity',
                    'p.seller_id',
                    'p.images as product_image',
                    'p.price as product_price',
                    'p.variables as product_variables',
                    'p.shipping',
                    'p.product_type',
                    'pd.name as product_name',
                    'ps.price as sku_price',
                    'ps.origin_price as sku_origin_price',
                    'ps.variants as sku_variants',
                    'ps.sku',
                    'ps.quantity as stock_quantity',
                    'ps.images as sku_images'
                ])
                ->select()
                ->toArray();
            if (empty($cartItems)) {
                throw new \Exception('购物车为空，请先添加商品');
            }

            // 检查库存
            foreach ($cartItems as $item) {
                if ($item['quantity'] > $item['stock_quantity']) {
                    throw new \Exception($item['product_name'] . ' 库存不足');
                }
            }

            // 2. 根据seller_id商户分组
            $groupedItems = [];
            $payGoodsDetail=[];
            foreach ($cartItems as $item) {
                $sellerId = $item['seller_id'] ?: 'platform'; // 0表示平台自营
                if (!isset($groupedItems[$sellerId])) {
                    $groupedItems[$sellerId] = [];
                }
                $groupedItems[$sellerId][] = $item;
                $payGoodsDetail[]=[
                    'merchant_goods_id' => (string)$item['product_id'],
                    'wechatpay_goods_id' => '',
                    'goods_name' => $item['product_name'],
                    'quantity' => $item['quantity'],
                    'unit_price' => ($item['sku_price'] > 0 ? $item['sku_price']*100 : $item['product_price']*100),
                ];
            }
            // 4. 获取优惠券信息并验证
            $couponInfo = null;
            $couponAmount = 0;
            // 5. 计算订单金额和优惠券分摊
            $totalAmount = 0;
            $ordersByGroup = [];

            foreach ($groupedItems as $sellerId => $items) {
                $groupTotal = 0;
                $processedItems = [];
                $seller = Sellers::where('id', $sellerId)
                    ->with('sellerGroups')
                    ->find();
                if ($seller) {
                    $sellerGroupRes = $seller->sellerGroups;
                } else {
                    $sellerGroupRes = ['fee_sale_flat' => 0, 'fee_sale_percent' => 0];
                }
                foreach ($items as $item) {
                    $price = $item['sku_price'] > 0 ? $item['sku_price'] : $item['product_price'];
                    $itemTotal = bcmul((string)$price, (string)$item['quantity'], 2);
                    $groupTotal = bcadd($groupTotal, $itemTotal, 2);

                    $item['unit_price'] = $price;
                    $item['item_total'] = $itemTotal;
                    $processedItems[] = $item;
                }

                $ordersByGroup[$sellerId] = [
                    'items' => $processedItems,
                    'subtotal' => $groupTotal,
                    'coupon_amount' => 0
                ];

                $totalAmount = bcadd($totalAmount, $groupTotal, 2);
            }

            // 计算优惠券优惠金额
            if ($couponInfo) {
                // 检查订单金额是否满足使用门槛
                if ($totalAmount < $couponInfo['min_spend']) {
                    throw new \Exception('订单金额不满足优惠券使用条件，需满' . $couponInfo['min_spend'] . '元');
                }

                // 计算优惠金额
                if ($couponInfo['discount_type'] == 1) { // 满减券
                    $couponAmount = $couponInfo['discount_amount'];
                } elseif ($couponInfo['discount_type'] == 2) { // 直减券
                    $couponAmount = $couponInfo['discount_amount'];
                } elseif ($couponInfo['discount_type'] == 3) { // 折扣券
                    $discountRate = bcdiv((string)$couponInfo['discount_rate'], '100', 4);
                    $couponAmount = bcsub($totalAmount, bcmul($totalAmount, $discountRate, 2), 2);
                }

                // 优惠金额不能超过订单总额
                if ($couponAmount > $totalAmount) {
                    $couponAmount = $totalAmount;
                }

                // 检查优惠券类型和商户限制
                if ($couponInfo['coupon_type'] == 2) { // 商家券
                    $targetSellerId = $couponInfo['site_id'];
                    if (!isset($ordersByGroup[$targetSellerId])) {
                        throw new \Exception('该商家优惠券不适用于当前商品');
                    }
                    // 商家券只能用于指定商家的商品
                    $ordersByGroup[$targetSellerId]['coupon_amount'] = $couponAmount;
                } else { // 平台券，按比例分摊到各个商家
                    foreach ($ordersByGroup as $sellerId => &$group) {
                        if ($totalAmount > 0) {
                            $ratio = bcdiv($group['subtotal'], $totalAmount, 4);
                            $group['coupon_amount'] = bcmul($couponAmount, $ratio, 2);
                        }
                    }
                }
            }
            // 计算最终支付金额
            $finalAmount = bcsub($totalAmount, $couponAmount, 2);
            // 6. 处理余额支付
            $balanceUsed = 0;
            $orderStatus = Orders::STATUS_UNPAID;
            $payStatus = Orders::PAY_STATUS_UNPAID;
            $orderPayementData = [];
            $paySn = '';
            Db::startTrans();
            if ($paymentType === 'balance') {
                // 检查用户余额
                $userBalance = $user['balance'] ?? 0;
                if ($userBalance < $finalAmount) {
                    throw new \Exception('余额不足，当前余额：' . $userBalance . '元');
                }
                $balanceUsed = $finalAmount;
                $orderStatus = Orders::STATUS_PAID;
                $payStatus = Orders::PAY_STATUS_PAID;
            } else {
                $orderStatus = Orders::STATUS_UNPAID;
                $payStatus = Orders::PAY_STATUS_UNPAID;
                $paySn = generateOrderNumber('P');
                $wechatPay = new WechatPaymentService();
                $payload = [
                    'body' => implode(',', array_column($cartItems, 'product_name')),
                    'order_sn' => $paySn,
                    'total_pay' => $finalAmount,
                    'openid' => $user['open_id'],
                    'client_ip' => request()->ip(),
                    'store_id' => '0001',
                    'store_name' => '喵旅',
                    'goods_detail' =>  $payGoodsDetail,
                    'total_amount'=>$totalAmount
                ];
                $resp = $wechatPay->pay($payload);
                PayRecord::insert([
                    'order_sn' => 0,
                    'seller_id' => 0,
                    'user_id' => $userId,
                    'pay_sn' => $paySn,
                    'pay_channel' => 'wechat',
                    'pay_method' => 'wechat',
                    'amount' => $finalAmount,
                    'status' => 0,
                    'created_at' => date('Y-m-d H:i:s'),
                ]);
                $orderPayementData = [
                    'transaction_id' => $paySn,
                    'request' => json_encode($payload),
                    'response'=>$resp,
                    'created_at' => date('Y-m-d H:i:s'),
                ];
            }
            // 7. 创建订单记录和相关明细
            $createdOrders = [];
            foreach ($ordersByGroup as $sellerId => $group) {
                // 生成订单号
                $orderNumber = generateOrderNumber('M');
                // 计算该订单组的实际支付金额
                $merchantAmount = $group['subtotal'];
                $groupFinalAmount = bcsub($group['subtotal'], $group['coupon_amount'], 2);
                // 创建订单记录
                $order = Orders::create([
                    'number' => $orderNumber,
                    'customer_id' => $userId,
                    'customer_group_id' => $user['customer_group_id'],
                    'shipping_address_id' => $addressId,
                    'customer_name' => $address['name'] ?? '',
                    'email' => $user['phone'] . '@163.com',
                    'telephone' => $user['phone'] ?? '',
                    'total' =>  $group['subtotal'],
                    'locale' => 'zh_cn',
                    'currency_code' => 'CNY',
                    'currency_value' => 1.00,
                    'ip' => request()->ip(),
                    'user_agent' => request()->header('User-Agent'),
                    'comment' => $remark,
                    'status' => $orderStatus,
                    'shipping_method_code' => 'seller',
                    'shipping_method_name' => '自动',
                    'shipping_customer_name' => $address['name'],
                    'shipping_telephone' => $address['phone'],
                    'shipping_country' => $address['country'] ?? '中国',
                    'shipping_country_id' => 44,
                    'shipping_zone' => $address['zone'],
                    'shipping_zone_id' => $address['zone_id'],
                    'shipping_city' => $address['city'],
                    'shipping_address_1' => $address['address_1'],
                    'shipping_address_2' => $address['address_1'],
                    'shipping_zipcode' => $address['zipcode'] ?? '000000',
                    'payment_method_code' => $paymentType,
                    'payment_method_name' => $paymentType === 'balance' ? '余额支付' : ($paymentType === 'wechat' ? '微信支付' : '支付宝支付'),
                    'seller_id' => $sellerId == 'platform' ? 0 : $sellerId,
                    'order_type' => Orders::TYPE_MALL,
                    'pay_status' => $payStatus,
                    'pay_time' => $payStatus == Orders::PAY_STATUS_PAID ? time() : null,
                    'code' => generateVerifyCode(10),
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                    'total_pay' => $groupFinalAmount,
                    'merchant_total_price' => $merchantAmount
                ]);

                // 创建订单产品明细
                foreach ($group['items'] as $item) {
                    // 计算该产品的优惠券分摊金额
                    $itemCouponAmount = 0;
                    if ($group['coupon_amount'] > 0) {
                        $itemRatio = bcdiv($item['item_total'], $group['subtotal'], 4);
                        $itemCouponAmount = bcmul($group['coupon_amount'], $itemRatio, 2);
                    }
                    $image = empty($item['sku_images']) ? (empty($item['product_image']) ? json_decode($item['product_image'], true)[0] : '') : json_decode($item['sku_images'], true)[0];
                    $skuVariants = empty($item['sku_variants']) ? [] : json_decode($item['sku_variants'], true);
                    // 数据[{"name": {"en": "color", "zh_cn": "颜色"}, "values": [{"name": {"en": "colro", "zh_cn": "蓝色"}, "image": ""}], "isImage": false}]
                    $productVariants = empty($item['product_variables']) ? [] : json_decode($item['product_variables'], true);
                    $variantText = '';
                    $variantDetails = [];

                    // 根据SKU variants索引获取对应的产品规格信息
                    if (!empty($skuVariants) && !empty($productVariants)) {
                        list($variantText, $variantDetails) = getSkuVariant($skuVariants, $productVariants);
                    }

                    OrderProducts::create([
                        'order_id' => $order->id,
                        'product_id' => $item['product_id'],
                        'order_number' => $orderNumber,
                        'product_sku' => $variantText,
                        'name' => $item['product_name'],
                        'image' => $image,
                        'quantity' => $item['quantity'],
                        'price' => $item['unit_price'],
                        'seller_id' => $sellerId == 'platform' ? 0 : $sellerId,
                        'store_commission_flat' => $sellerGroupRes['fee_sale_flat'],
                        'store_commission_percent' => $sellerGroupRes['fee_sale_percent'],
                        'seller_amount' => $item['item_total'],
                        'coupon_amount' => $itemCouponAmount,
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s')
                    ]);
                }

                // 记录优惠券使用
                if ($couponInfo && $group['coupon_amount'] > 0) {
                    OrderCoupon::create([
                        'user_id' => $userId,
                        'coupon_id' => $couponId,
                        'order_id' => $order->id,
                        'order_amount' => $group['subtotal'],
                        'coupon_amount' => $group['coupon_amount'],
                        'dedu_coupon_amount' => $group['coupon_amount'],
                        'created_at' => date('Y-m-d H:i:s')
                    ]);
                }

                // 创建订单金额构成记录
                $totalLog = [];
                $totalLog[] = [
                    'order_id' => $order->id,
                    'code' => OrderTotals::CODE_SUBTOTAL,
                    'value' => $group['subtotal'],
                    'title' => '商品总计',
                    'reference' => json_encode(['items_count' => count($group['items'])]),
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s')
                ];

                if ($group['coupon_amount'] > 0) {
                    $totalLog[] = [
                        'order_id' => $order->id,
                        'code' => OrderTotals::CODE_COUPON,
                        'value' => -$group['coupon_amount'],
                        'title' => '优惠券优惠',
                        'reference' => json_encode(['coupon_id' => $couponId, 'coupon_name' => $couponInfo['name']]),
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s')
                    ];
                }
                $totalLog[] = [
                    'order_id' => $order->id,
                    'code' => OrderTotals::CODE_TOTAL_PAY,
                    'value' => $groupFinalAmount,
                    'title' => '订单总计',
                    'reference' => json_encode(['payment_type' => $paymentType]),
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s')
                ];

                OrderTotals::insertAll($totalLog);
                $createdOrders[] = [
                    'order_id' => $order->id,
                    'order_number' => $orderNumber,
                    'amount' => $groupFinalAmount,
                    'seller_id' => $sellerId
                ];
                if (!empty($orderPayementData)) {
                    $orderPayementData['order_id'] = $order->id;
                    OrderPayments::insert($orderPayementData);
                }

                if ($paymentType == 'balance') {
                    User::decUserBalance($userId, $order->id, $group['subtotal'], '商城订单支付');
                }
            }

            // 更新优惠券使用状态
            if ($couponInfo) {
                TravelCouponUser::where('id', $userCoupon['id'])
                    ->update([
                        'status' => 2, // 已使用
                        'used_at' => date('Y-m-d H:i:s'),
                        'order_id' => implode(',', array_column($createdOrders, 'order_id'))
                    ]);
            }
            // 清空购物车选中商品
            CartProducts::where('customer_id', $userId)
                ->where('selected', 1)
                ->delete();

            Db::commit();

            return [
                'message' => '订单创建成功',
                'orders' => $createdOrders,
                'total_amount' => $totalAmount,
                'coupon_amount' => $couponAmount ?? 0,
                'final_amount' => $finalAmount,
                'balance_used' => $balanceUsed,
                'status' => $orderStatus,
                'wx_pay_data' => empty($orderPayementData)?'':$orderPayementData['response'],
            ];
        } catch (\Exception $e) {
            Db::rollback();
            throw $e;
        }
    }

    /**
     * 获取商城订单列表
     * @param int $userId 用户ID
     * @param int $page 页码
     * @param int $pageSize 每页数量
     * @param string $status 订单状态筛选
     * @return array
     */
    public static function getMallOrderList($userId, $page = 1, $pageSize = 10, $status = '')
    {
        $where = [];
        $where[] = ['o.customer_id', '=', $userId];
        $where[] = ['o.order_type', '=', Orders::TYPE_MALL];
        // 状态筛选
        if (!empty($status)) {
            // pending=unpaid
            // paid=paid
            // shipped=shipped
            // completed=completed
            // $where[] = ['o.status', '=', $status];
            switch ($status) {
                case 'pending':
                    $where[] = ['o.status', '=', Orders::STATUS_UNPAID];
                    break;
                case 'paid':
                    $where[] = ['o.status', '=', Orders::STATUS_PAID];
                    break;
                case 'shipped':
                    $where[] = ['o.status', '=', Orders::STATUS_SHIPPED];
                    break;
                case 'completed':
                    $where[] = ['o.status', '=', Orders::STATUS_COMPLETED];
                    break;
                case 'cancelled':
                    $where[] = ['o.status', '=', Orders::STATUS_CANCELLED];
                    break;
            }
        }

        // 查询订单列表，关联订单产品和商户信息
        $query = Orders::alias('o')
            ->leftJoin('order_products op', 'o.id = op.order_id')
            ->leftJoin('sellers s', 'o.seller_id = s.id')
            ->where($where)
            ->field([
                'o.id',
                'o.number as order_number',
                'o.status',
                'o.pay_status',
                'o.total',
                'o.total_pay',
                'o.payment_method_name',
                'o.created_at',
                'o.pay_time',
                'o.comment',
                'o.seller_id',
                's.store_name',
                's.logo as seller_logo'
            ])
            ->group('o.id')
            ->order('o.id', 'desc');

        // 分页查询
        $total = Orders::alias('o')
            ->where($where)
            ->count();

        $list = $query->limit($page, $pageSize)->select()->toArray();

        // 获取每个订单的产品信息
        if (!empty($list)) {
            $orderIds = array_column($list, 'id');

            // 查询订单产品明细
            $orderProducts = OrderProducts::alias('op')
                // ->leftJoin('products p', 'op.product_id = p.id')
                ->whereIn('op.order_id', $orderIds)
                ->select()
                ->toArray();

            // 按订单ID分组产品
            $productsByOrder = [];
            foreach ($orderProducts as $product) {
                $product['image'] = env('IMAGE_URL') . $product['image'];
                $productsByOrder[$product['order_id']][] = $product;
            }

            // 查询订单金额构成
            $orderTotals = OrderTotals::whereIn('order_id', $orderIds)
                ->select()
                ->toArray();

            $totalsByOrder = [];
            foreach ($orderTotals as $total) {
                $totalsByOrder[$total['order_id']][] = $total;
            }

            // 组装订单数据
            foreach ($list as &$order) {
                // 订单状态描述
                $order['status_text'] = Orders::getOrderStatusText($order['status']);
                $order['pay_status_text'] = $order['pay_status'] == Orders::PAY_STATUS_PAID ? '已支付' : '待支付';

                // 格式化金额
                $order['total'] = round((float)$order['total'], 2);
                $order['total_pay'] = round((float)$order['total_pay'], 2);

                // 格式化时间
                $order['created_at'] = date('Y-m-d H:i:s', strtotime($order['created_at']));
                $order['pay_time'] = $order['pay_time'] ? date('Y-m-d H:i:s', $order['pay_time']) : '';

                // 商户信息
                if ($order['seller_id'] == 0) {
                    $order['seller_name'] = '平台自营';
                    $order['seller_logo'] = '';
                } else {
                    // 处理商户logo URL
                    if ($order['seller_logo'] && strpos($order['seller_logo'], 'http') !== 0) {
                        $order['seller_logo'] = env('IMAGE_URL') . $order['seller_logo'];
                    }
                }

                // 订单产品列表
                $order['products'] = $productsByOrder[$order['id']] ?? [];
                // foreach ($order['products'] as &$product) {
                //     // 处理产品图片URL&& strpos($product['product_image'], 'http') !== 0
                //     if ($product['product_image'] ) {
                //         $product['product_image'] = env('IMAGE_URL') . $product['product_image'];
                //     }
                //     $product['price'] = round((float)$product['price'], 2);
                // }
                // 订单金额构成
                $order['totals'] = $totalsByOrder[$order['id']] ?? [];

                // 计算订单商品总数量
                $order['total_quantity'] = array_sum(array_column($order['products'], 'quantity'));
            }
        }

        // 计算是否还有更多数据
        $hasMore = ($page * $pageSize) < $total;
        return [
            'list' => $list,
            'total' => $total,
            'page' => $page,
            'pageSize' => $pageSize,
            'hasMore' => $hasMore
        ];
    }


    // 确认收货
    public static function confirmMallOrderReceipt($orderId)
    {
        // 获取当前用户
        $userId = UserService::getCurrentUserId();
        $order = Orders::where('id', $orderId)->where('customer_id', $userId)->find();
        if (!$order) {
            throw new \Exception('订单不存在');
        }
        if ($order['status'] != Orders::STATUS_SHIPPED) {
            throw new \Exception('订单状态错误');
        }
        Orders::where('id', $orderId)->update([
            'status' => Orders::STATUS_COMPLETED,
            'updated_at' => date('Y-m-d H:i:s'),
        ]);
        return true;
    }


    // 申请退款
    public static function applyMallOrderRefund($orderId)
    {
        // 获取当前用户
        $userId = UserService::getCurrentUserId();
        $order = Orders::where('id', $orderId)->where('customer_id', $userId)->with('orderProducts')->find();
        if (!$order) {
            throw new \Exception('订单不存在');
        }
        if ($order['status'] != Orders::STATUS_PAID) {
            throw new \Exception('订单状态错误');
        }
        if ($order['payment_method_code'] == 'balance') {
            //退款余额
            // OrderCoupon
            // 退余额，记录钱包记录，更改订单状态
            try {
                Db::startTrans();
                // 退回余额
                User::incUserBalance($userId, $order['id'], $order['total_pay'], '用户申请退货订单');
                //    获取优惠卷
                Orders::where('id', $orderId)->update([
                    'status' => Orders::STATUS_CANCELLED, //cancelled
                ]);
                OrderHistories::createHistory($orderId, Orders::STATUS_CANCELLED, '用户申请退货订单');
                $orderCoupon = OrderCoupon::where('order_id', $orderId)->find();
                if (!empty($orderCoupon)) {
                    // 判断是否全部订单都退款了
                    $coids = OrderCoupon::where([
                        'coupon_id' => $orderCoupon['coupon_id'],
                        'user_id' => $order['customer_id']
                    ])->field('order_id')->select()->toArray();
                    if (count($coids) == Orders::whereIn('id', array_column($coids, 'order_id'))->where('status', 'cancelled')->count()) {
                        // 退优惠卷
                        TravelCouponUser::where('id', $orderCoupon['coupon_id'])
                            ->update([
                                'status' => 1, // 已使用
                                'used_at' => date('Y-m-d H:i:s'),
                                'order_id' => ''
                            ]);
                    }
                }
                // 插入售后表rmas，rma_histories，rma_reasons
                foreach ($order['orderProducts'] as $goods) {
                    // $rmareasonsId = RmaReasons::insertGetId([
                    //     'name' => json_encode(['zh_cn' => '不想要']),
                    //     'created_at' => date('Y-m-d H:i:s'),
                    //     'updated_at' => date('Y-m-d H:i:s'),
                    // ]);
                    $rmaId = Rmas::insertGetId([
                        'order_id' => (int)$order['id'],
                        'order_product_id' => (int)$goods['id'],
                        'customer_id' => $userId,
                        'name' => $order['shipping_customer_name'],
                        'email' => '',
                        'telephone' => $order['shipping_telephone'],
                        'product_name' => $goods['name'],
                        'sku' => $goods['product_sku'],
                        'quantity' => $goods['quantity'],
                        'images' => json_encode([]),
                        'opened' => 0,
                        'rma_reason_id' => 7, //默认// $rmareasonsId,
                        'type' => Rmas::TYPE_REFUND,
                        'status' => Rmas::STATUS_COMPLETED,
                        'comment' => '已退余额',
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s'),
                    ]);
                    RmaHistories::insert([
                        'rma_id' => $rmaId,
                        'status' => Rmas::STATUS_COMPLETED,
                        'notify' => 0,
                        'comment' => '已退余额',
                        'created_at' => date('Y-m-d H:i:s'),
                        'updated_at' => date('Y-m-d H:i:s'),
                    ]);
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                trace($e, 'error');
                throw new \Exception($e->getMessage());
                return ['data' => '', 'msg' => '退款失败'];
            }
            return ['data' => '', 'msg' => '退款成功'];
        }
    }
}
